#include "include.h"

/****************************************************************
 *This function is thread5
 *	(1)create socket,listen port,process command
 ****************************************************************/
void *thread5(void *str)
{
	// 接收组播部分
	int socked;  
	char group[16]="235.0.168.160";
	struct sockaddr_in local_addr;
	struct ip_mreq mreq; // 多播地址结构体

	unsigned int temp_i = 0, rd_data, opt_place = 0, net_send_len = 0;

	unsigned int timeout = 0;
	unsigned int fifo_len_valid = 0;

	// 清空局部变量
	memset(&local_addr,0,sizeof(local_addr));

	// 建立socket
	socked=socket(AF_INET,SOCK_DGRAM,0); 

	// 填充组播信息
	local_addr.sin_family=AF_INET;
	local_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	local_addr.sin_port=htons(BOARDCAST_REV_PCM_PORT_TWO);

	// 绑定本地端口
	bind(socked,(struct sockaddr*)&local_addr,sizeof(local_addr));

	// 加入组播组
	mreq.imr_multiaddr.s_addr=inet_addr(group);
	mreq.imr_interface.s_addr = inet_addr("192.168.251.251");
	setsockopt(socked,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));

	// 建立应答组播socket
    // 建立应答组播套接字
	int sock_send;
	sock_send = socket(AF_INET, SOCK_DGRAM, 0);

	struct in_addr opt;
    inet_pton(AF_INET, "235.0.168.160", &opt.s_addr);
    setsockopt(sock_send, IPPROTO_IP, IP_MULTICAST_IF, &opt, sizeof(opt));
    struct sockaddr_in cliaddr;
    int len = sizeof(cliaddr);
    cliaddr.sin_family = AF_INET;
    cliaddr.sin_port = htons(BOARDCAST_REV_PCM_PORT_TWO);
    inet_pton(AF_INET, "235.0.168.160", &cliaddr.sin_addr.s_addr);

	// 给出线程运行提示信息
	fprintf(stderr,"thread five running\n");

	while(1){
		// 延时查询
		usleep(100);

		// 读取HDLC缓冲区中数据大小
		pcm_rd_date_length_two = 0;
		dev_32bit_read(mmap_addr, 0x14, &pcm_rd_date_length_two);
		
		// 判断fifo的数据区是否有效
		fifo_len_valid = 0;
		fifo_len_valid = pcm_rd_date_length_two & 0xfffff800;
		if(fifo_len_valid != 0){
			continue;
		}

		// 获取有效数据的长度
		pcm_rd_date_length_two &= 0x7ff;
		if(pcm_rd_date_length_two >= pcm_once_read_len_two){
			// 超时清空
			timeout = 0;

			// 读取数据
			for(temp_i = 0; temp_i < pcm_once_read_len_two; temp_i ++){
				opt_place = temp_i * 4;
				dev_32bit_read(mmap_addr, 0x1c, &rd_data); 
				pcm_rd_data_buffer_two[opt_place + 0] = (char)(rd_data >> 24);
				pcm_rd_data_buffer_two[opt_place + 1] = (char)(rd_data >> 16);
				pcm_rd_data_buffer_two[opt_place + 2] = (char)(rd_data >> 8);
				pcm_rd_data_buffer_two[opt_place + 3] = (char)(rd_data >> 0);
			}

			// 组播发送
			net_send_len = pcm_once_read_len_two << 2;
			sendto(sock_send, pcm_rd_data_buffer_two, net_send_len, 0, \
					(struct sockaddr*)&cliaddr, len);
		} else if((pcm_rd_date_length_two > 0) && (pcm_rd_date_length_two < pcm_once_read_len_two)){
			// 超时增加个
			timeout ++;
			if(timeout >= 10000){
				timeout = 0;

				// 读取数据
				for(temp_i = 0; temp_i < pcm_rd_date_length_two; temp_i ++){
					opt_place = temp_i * 4;
					dev_32bit_read(mmap_addr, 0x1c, &rd_data); 
					pcm_rd_data_buffer_two[opt_place + 0] = (char)(rd_data >> 24);
					pcm_rd_data_buffer_two[opt_place + 1] = (char)(rd_data >> 16);
					pcm_rd_data_buffer_two[opt_place + 2] = (char)(rd_data >> 8);
					pcm_rd_data_buffer_two[opt_place + 3] = (char)(rd_data >> 0);
				}

				// 组播发送
				net_send_len = pcm_rd_date_length_two << 2;
				sendto(sock_send, pcm_rd_data_buffer_two, net_send_len, 0, \
						(struct sockaddr*)&cliaddr, len);
			}
		} else {
			;
		}
	}

	return NULL;
}

